<script setup lang="ts">
import type { BasicOption } from '@/lib/typings';

import type { AppTypeProps } from '@/types';

import {
  type ComponentInternalInstance,
  computed,
  defineAsyncComponent,
  getCurrentInstance,
  hydrateOnVisible,
  onMounted,
  ref,
  useTemplateRef,
  watch,
} from 'vue';

import { Icon } from '@/components/core/icon';

import { ElButton, ElMessage, ElMessageBox, ElSelect } from 'element-plus';
import { EDesigner, type PageSchema } from 'epic-designer';
import { customAlphabet } from 'nanoid';

defineOptions({
  name: 'WorkDesign',
});
const nanoid = customAlphabet('abcdefghijklmnopqrstuvwxyz', 10);
const AppEdit = defineAsyncComponent({
  hydrate: hydrateOnVisible(),
  loader: () => import('../_core/common/AppEdit.vue'),
});

const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const baseUrl = proxy?.$config.baseUrl;
const designerRef = ref<InstanceType<typeof EDesigner>>();
const appEditElRef = useTemplateRef('appEditElRef');
const projectValue = ref<string>();
const projectName = '新建项目';
const projectOptions = ref<BasicOption[]>([]);
const hasNewProject = computed(() => {
  return projectOptions.value.some((item: BasicOption) => item.value === 'new');
});
const pageSchema = {
  schemas: [
    {
      componentProps: {
        name: projectName,
        style: {
          padding: '16px',
        },
      },
      id: 'root',
      label: '页面',
      type: 'page',
      children: [],
    },
  ],
};
/**
 * 点击保存按钮操作
 * @param e
 */
function handleSubmit(e: PageSchema) {
  const pageName = e.schemas[0]?.componentProps.name;
  if (!pageName) {
    ElMessage.error('请输入项目页面名称');
    return;
  }

  const currProject = projectOptions.value.find((item: BasicOption) => {
    return item.value === projectValue.value;
  });
  if (currProject) {
    Object.assign(currProject, { label: pageName });
    if (currProject.value === 'new') {
      projectValue.value = nanoid();
      Object.assign(currProject, { value: projectValue.value });
    }
  }

  const options = projectOptions.value.filter((item: BasicOption) => item.value !== 'new');
  const body = {
    mapping: options,
    schema: e,
  };
  const url = `${baseUrl}/design/save/${projectValue.value}`;
  fetch(url, {
    body: JSON.stringify(body),
    headers: {
      'Content-Type': 'application/json;charset=utf-8',
    },
    method: 'POST',
  })
    .then((response) => response.json())
    .then((res) => {
      const { code, msg } = res;
      if (code === 200) {
        ElMessage.success(msg);
      } else {
        ElMessage.error(msg);
      }
    });
}
// 切换项目
const onProjectChange = (value: string) => {
  if (!value || value === 'new') return;
  let schemas: PageSchema = pageSchema;
  const url = `${baseUrl}/design/project/${value}`;
  fetch(url, {
    method: 'GET',
  })
    .then((response) => response.json())
    .then((res) => {
      const { code, data } = res;
      if (code === 200 && data) {
        schemas =
          typeof data === 'string'
            ? (JSON.parse(data) as PageSchema)
            : (data as PageSchema);
      }
      designerRef.value?.setData(schemas);
    });
};
// 创建新项目
function loadNewProject() {
  projectValue.value = 'new';
  projectOptions.value.push({
    label: projectName,
    value: 'new',
  });
  designerRef.value?.setData(pageSchema);
}
// 加载项目选项
function loadProjectMapping() {
  const url = `${baseUrl}/design/mapping`;
  fetch(url, {
    method: 'GET',
  })
    .then((response) => response.json())
    .then((res) => {
      const { code, data } = res;
      if (code === 200 && data) {
        projectOptions.value =
          typeof data === 'string' ? (JSON.parse(data) as BasicOption[]) : data;
      }
      loadNewProject();
    });
}
// 删除项目
function handleDelProject() {
  const id = projectValue.value;
  ElMessageBox.confirm('确定要删除当前项目吗？', '提示', {
    cancelButtonText: '取消',
    confirmButtonText: '确定',
    type: 'warning',
  }).then(() => {
    const url = `${baseUrl}/design/delete/${id}`;
    const options = projectOptions.value.filter((item: BasicOption) => item.value !== id);
    const body = {
      mapping: options,
    };
    fetch(url, {
      body: JSON.stringify(body),
      headers: {
        'Content-Type': 'application/json;charset=utf-8',
      },
      method: 'DELETE',
    })
      .then((response) => response.json())
      .then((res) => {
        const { code, msg } = res;
        if (code === 200) {
          projectOptions.value = options;
          ElMessage.success(msg);
          projectValue.value = projectOptions.value[0]?.value || 'new';
          // 删除对应的图标
          const url = `${baseUrl}/app/delete/system_${id}?type=custom`;
          fetch(url, { method: 'DELETE' });
        } else {
          ElMessage.error(msg || '删除失败，请稍后再试');
        }
      });
  });
}
// 生成应用
function onBuildApp(data: AppTypeProps) {
  const id = projectValue.value;
  const url = `${baseUrl}/app/save/system_${id}`;
  fetch(url, {
    body: JSON.stringify(data),
    headers: {
      'Content-Type': 'application/json;charset=utf-8',
    },
    method: 'POST',
  })
    .then((response) => response.json())
    .then((res) => {
      const { code, msg } = res;
      if (code === 200) {
        ElMessage.success(msg || '应用信息保存成功');
      } else {
        ElMessage.error(msg || '删除失败，请稍后再试');
      }
    });
}
function handleBuildApp() {
  const id = projectValue.value;
  if (!id || id === 'new') return;
  const app = projectOptions.value.find((item: BasicOption) => item.value === id);
  if (app) {
    appEditElRef.value?.open(app);
  }
}
onMounted(() => {
  loadProjectMapping();
});
watch(
  () => projectValue.value,
  (value) => {
    onProjectChange(value as string);
  },
);
</script>

<template>
  <div class="wos-design">
    <EDesigner ref="designerRef" @save="handleSubmit">
      <template #header-title>
        <ElSelect
      v-model="projectValue"
      placeholder="新建项目"
      size="small"
      style="width: 240px"
    >
      <ElOption
        v-for="item in projectOptions"
        :key="item.value"
        :label="item.label"
        :value="item.value"
      />
    </ElSelect>
        
        <ElButton
          :disabled="hasNewProject"
          class="ml-2"
          size="small"
          @click="loadNewProject"
        >
          <Icon class="mr-1" icon="ant-design:plus-outlined" />
          新建项目
        </ElButton>
        <ElButton
          :disabled="projectValue === 'new'"
          class="ml-2"
          size="small"
          @click="handleDelProject"
        >
          <Icon class="mr-1" icon="ant-design:delete-outlined" />
          删除
        </ElButton>
        <ElButton
          :disabled="projectValue === 'new'"
          class="ml-2"
          size="small"
          @click="handleBuildApp"
        >
          <Icon class="mr-1" icon="ant-design:appstore-add-outlined" />
          生成应用
        </ElButton>
      </template>
      <template #header-prefix>
        <div>Designer</div>
      </template>
    </EDesigner>
    <Teleport to="body">
      <AppEdit ref="appEditElRef" @confirm="onBuildApp" />
    </Teleport>
  </div>
</template>

<style lang="scss">
@import url('./css/design.scss');
</style>
